Software network functions (NFs) are software applications that implement advanced traffic processing functions; i.e., inspecting, modifying, or otherwise processing the packets in a network traffic stream. Examples of NFs include network intrusion detection systems (IDS), protocol or WAN optimizers, firewalls, Network Address Translators (NATs), and so forth. Within a network, different traffic streams may be processed by different network function virtualization (NFV) services. An NFV service can include a single NF, or a chained sequence of NFs. In a typical scenario, a network operator will define how different traffic streams should be processed by an NFV service using a high-level abstraction—e.g., using an abstract modeling language such as TOSCA (Topology and Orchestration Specification for Cloud Applications) or a graphical user interface (GUI). This high-level specification, referred to as a network function virtualization (NFV) policy graph, is an NFV policy specification which defines how traffic should be processed by different NFs of an NFV service and may be applied to all traffic to/from a particular customer or tenant of a network. Additionally, the NFV policy specification may optionally include constraints such as target performance levels (min and/or max) of the NFs or other components of the network. Many steps are involved in executing an NFV policy specification such as described above. For example, a set of resources (e.g., CPU cores, memory) must be allocated to run the required NFs; the appropriate NF images (e.g., virtual machines (VMs), containers, or processes) must be launched and configured; relevant network elements must be configured to correctly steer traffic through the correct sequence of NFs of the NFV service as specified by the NFV policy specification, and so forth. These steps are required for initially setting up an NFV deployment in accordance with the NFV policy specification. Additional steps are also required to maintain the operation of this deployment: e.g., adjusting the number of NF instances as the traffic load changes, detecting and recovering from failure, and so forth.
Conventional systems for deploying and maintaining NFs within a network are typically either implemented as monolithic software entities or are implemented as tightly coupled modules which communicate via pairwise application programming interfaces (APIs). Conventional systems implemented as monolithic software entities are often hard to extend and maintain because developers of such systems have to understand the entire system in order to test or modify it. Conventional systems which are implemented as tightly coupled modules which communicate via pairwise APIs are often hard to extend or modify because changing a workflow of such systems requires modifying the pairwise APIs, which often then requires modules of the system to be changed to support the modified APIs. Conventional systems that use pairwise APIs are also vulnerable to “lock-in” because replacing a module of the system with a module offered from another vendor often requires also replacing every module of the system that used the replaced module. Additionally, modules of conventional systems often hold system state internally, which complicates the architecting of resilient systems. For instance, in conventional systems, multiple instances of the same module will typically be instantiated within the network, and those instances perform a computationally heavy state replication and consensus algorithm between themselves.